﻿using System;
using System.Collections.Generic;
using TopShooter.Items;
using Microsoft.Xna.Framework;
using TopShooter.Units;

namespace TopShooter
{
	public abstract class Unit : Entity
	{
		public Weapon Weapon;

		public Armor Armor;

		public float MovementSpeed;
		public float MovementRemaining;
		public float Strength;
		public double EarliestTimeForNextAttack;

		public Vector2 Direction = new Vector2(0,1);
		public float WeaponRotation = 1;

		public float AIupdateRate = 0.4f;
		private double _timeForNextAI;

		public IEnumerable<Item> EquippedItems
		{
			get
			{
				if (Weapon != null)
					yield return Weapon;
				if (Armor != null)
					yield return Armor;
			}
		}

		public List<UnitCommand> CommandQueue = new List<UnitCommand>();
		public List<Activity> Activities = new List<Activity>();

		public Unit(int team)
		{
			TeamID = team;
			Color = (team == 1) ? Color.Blue : Color.Red;
		}

		public virtual void IssueDefaultCommand(Vector2 loc, bool append)
		{
			if (!append)
			{
				AbortAllCommands();
			}
			Entity e = Scene.FindSelectableEntityAtLocation((int)loc.X, (int)loc.Y);
			UnitCommand command;
			if (e == null)
			{
				command = new UnitCommand.Move(loc);
			}
			else
			{
				command = new UnitCommand.Follow(loc);
			}
			AddCommand(command);
		}
		public override void Update(GameTime gameTime)
		{
			if (CommandQueue.Count > 0)
			{
				WeaponRotation = MathUtil.GetRotation(Direction);
				UnitCommand c = CommandQueue[0];
				c.Update(Game.Instance.TimeDelta);
				if (c.TimeRemaining <= 0)
				{
					CommandQueue.RemoveAt(0);
				}
			}
			for (int i = Activities.Count - 1; i >= 0; i--)
			{
				var a = Activities[i];
				bool hasCompleted = a.Update(Game.Instance.TimeDelta);
				if (hasCompleted)
				{
					Activities.RemoveAt(i);
				}
			}
			if (Game.Instance.Seconds >= _timeForNextAI)
			{
				_timeForNextAI = Game.Instance.Seconds + 1;
				OnAIupdate();
			}
			base.Update(gameTime);
		}

		public UnitCommand CurrentCommand { get { return (CommandQueue.Count > 0) ? CommandQueue[0] : null; } }

		public void AbortAllCommands()
		{
			if (CurrentCommand != null)
			{	// First abort the current command
				CurrentCommand.Abort();
			}
			CommandQueue.Clear();
		}

		public void AddCommand(UnitCommand command)
		{
			command.Attach(this);
			CommandQueue.Add(command);
		}

		public override bool TakeDamage(float damage, Entity entity)
		{
			if (CurrentCommand == null || !CurrentCommand.WasUserIssued)
			{
				UnitCommand.Attack ac = CurrentCommand as UnitCommand.Attack;

				if (ac == null || ac.TargetEntity != entity)
				{
					if (ac != null)
					{
						AbortAllCommands();
					}
					ac = new UnitCommand.Attack(entity);
					ac.WasUserIssued = false;
					AddCommand(ac);
				}
			}
			return base.TakeDamage(damage, entity);
		}

		virtual protected void OnAIupdate()
		{
		}
		public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Vector2 offset)
		{
			if (Weapon != null)
			{
				Weapon.Draw(spriteBatch, offset);
			}
			base.Draw(spriteBatch, offset);
			if (Armor != null)
			{
				Armor.Draw(spriteBatch, offset);
			}
			
		}
		protected override void OnLoadContent()
		{
			base.OnLoadContent();
			foreach (var item in EquippedItems)
			{
				item.OnLoadContent();
			}
		}
		protected override void OnUnloadContent()
		{
			base.OnUnloadContent();
		}

		protected override void OnRemoveFromScene()
		{
			base.OnRemoveFromScene();

			if (Game.IsEditorMode)
			{
				if (Editor.GameEditorPlayer.Instance != null)
					Editor.GameEditorPlayer.Instance.Selections.SelectedEntities.Remove(this);	
			}
			else
			{
				if (GodPlayer.Instance != null)
					GodPlayer.Instance.Selections.SelectedEntities.Remove(this);
			}
		}
	}
}
